﻿using Mapster;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YY.Admin.Core.Session;
using YY.Admin.Services.Service.Role;
using YY.Admin.Services.Service.User;

namespace YY.Admin.Services.Service.Menu
{
    public class SysMenuService : ISysMenuService, ISingletonDependency
    {
        private readonly ISqlSugarClient _dbContext;
        private readonly SysUserRoleService _sysUserRoleService; 
        private readonly SysRoleMenuService _sysRoleMenuService; 
        public SysMenuService(
            ISqlSugarClient context,
                 SysRoleMenuService sysRoleMenuService,
            SysUserRoleService sysUserRoleService) {
            _dbContext=context;
            _sysUserRoleService=sysUserRoleService;
            _sysRoleMenuService=sysRoleMenuService;
        }
        /// <summary>
        /// 获取登录菜单树
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuOutput>> GetLoginMenuTree()
        {
            var (query, _) = GetSugarQueryableAndTenantId(AppSession.CurrentUser.TenantId!.Value);
            if (AppSession.CurrentUser!.IsSuperAdmin || AppSession.CurrentUser!.IsSysAdmin)
            {
                var menuList = await query.Where(u => u.Type != MenuTypeEnum.Btn && u.Status == StatusEnum.Enable)
                    .OrderBy(u => new { u.OrderNo, u.Id })
                    .ToTreeAsync(u => u.Children, u => u.Pid, 0);
                return menuList.Adapt<List<MenuOutput>>();
            }
            var menuIdList = await GetMenuIdList();
            var menuTree = await query.Where(u => u.Type != MenuTypeEnum.Btn && u.Status == StatusEnum.Enable)
                .OrderBy(u => new { u.OrderNo, u.Id }).ToTreeAsync(u => u.Children, u => u.Pid, 0, menuIdList.Select(d => (object)d).ToArray());
            return menuTree.Adapt<List<MenuOutput>>();
        }
        /// <summary>
        /// 获取当前用户菜单Id集合
        /// </summary>
        /// <returns></returns>
        public async Task<List<long>> GetMenuIdList()
        {
            var roleIdList = await _sysUserRoleService.GetUserRoleIdList(AppSession.CurrentUser.Id);
            return await _sysRoleMenuService.GetRoleMenuIdList(roleIdList);
        }
        /// <summary>
        /// 根据租户id获取构建菜单联表查询实例
        /// </summary>
        /// <param name="tenantId"></param>
        /// <returns></returns>
        public (ISugarQueryable<SysMenu, SysTenantMenu> query, long tenantId) GetSugarQueryableAndTenantId(long tenantId)
        {
            if (!AppSession.CurrentUser!.IsSuperAdmin) tenantId = AppSession.CurrentUser.TenantId!.Value;

            // 超管用户菜单范围：种子菜单 + 租户id菜单
            ISugarQueryable<SysMenu, SysTenantMenu> query;
            if (AppSession.CurrentUser.IsSuperAdmin)
            {
                if (tenantId <= 0)
                {
                    query = _dbContext.Queryable<SysMenu>().InnerJoinIF<SysTenantMenu>(false, (u, t) => true);
                }
                else
                {
                    // 指定租户的菜单
                    var menuIds = _dbContext.Queryable<SysTenantMenu>().Where(u => u.TenantId == tenantId).ToList(u => u.MenuId) ?? new();

                    // 种子菜单
                    //menuIds.AddRange(new SysMenuSeedData().HasData().Select(u => u.Id).ToList());

                    menuIds = menuIds.Distinct().ToList();
                    query = _dbContext.Queryable<SysMenu>().InnerJoinIF<SysTenantMenu>(false, (u, t) => true).Where(u => menuIds.Contains(u.Id));
                }
            }
            else
            {
                query = _dbContext.Queryable<SysMenu>().InnerJoinIF<SysTenantMenu>(tenantId > 0, (u, t) => t.TenantId == tenantId && u.Id == t.MenuId);
            }

            return (query, tenantId);
        }

    }
}
